#include <stdlib.h>
#include <stdio.h>

#include <windows.h>

#include "lib.h"
#include "slotserv.h"
#include "log.h"
#include "logger.h"
#include "getrand.h"
#include "casbase.h"

#include "stdolog.h"

static SlotServer* serv = (SlotServer*)0;

static BOOL __stdcall ctrlHandler(DWORD);

void main(int c, char *v[])
{
	int port = 2063;

	if (c == 2)
		port = atoi(v[1]);

	SetConsoleCtrlHandler(ctrlHandler, TRUE);

	CasinoBase::load();
	port += CasinoBase::baseport;

	if (CasinoBase::baseport)
		printf("\n*** port adjusted by %d:  listening on %d\n",
			CasinoBase::baseport, port);
	else
		printf("\n*** listening on %d\n", port);

	Log::init(new StdoutLogger());
	serv = new SlotServer(port);
	if (serv)
		serv->run();
	delete serv;
	Log::uninit();
}

uint32 getrand()
{
	return serv->rand();
}

////////////////////////////////////////////////////////////////////////////
/// @fn 	 getRandomLessThan( uint32 nUpperBound )
///
/// @param   nUpperBound	The upper bound that the random number should be
///                         lower than.
///
/// This function gets a random number from 0 to less than the upper bound
/// with each possible result having an equal chance of being returned.
////////////////////////////////////////////////////////////////////////////
uint32 getRandomLessThan( uint32 nUpperBound )
{
    // getrand returns a uint32, so the maximum possible value is 0xFFFFFFFF
    uint32 nMaxRand = 0xFFFFFFFF;

    // Now if the maximum random value is not evenly divisible by the upper bound
    // of the random number they want, then the possible random values are not
    // evenly distributed across each possible result.  For example, if the maximum
    // possible random number were 25, and the upper bound was 10, then the values
    // 20 through 25 would skew the odds and cause the possible results of 0 through
    // 5 to occur slightly more often than 6 throuh 9.  So we need to calculate the
    // maximum random number that would result in an even distribution.  Any random
    // number that is greater than or equal to that should be thrown out so that the 
    // results are not skewed.

    // Divide the total number range by the upper bound to see how many evenly
    // distributed possibilities there are for each result.
    uint32 nNumChancesForEachResult = nMaxRand / nUpperBound;

    // Now calculate the maximum random value that would give us an equal
    // distribution among the possible results.
    uint32 nMaxRandForEqualDistribution = nNumChancesForEachResult * nUpperBound;

    // Declare a local variable to store the random number.
    uint32 nRand;

    do
    {
        // Get a random number.
        nRand = getrand();
    }
    // If the random number is greater than or equal to the maximum value for an 
    // equal distribution then throw it out and get another random value.
    // Note:  If nRand == nMaxEvenlyDistributedRand then a result of 0 would have
    // one extra chance to hit compared to the other possible results, so we have
    // to use >= for the loop condition to throw that value out as well.
    while ( nRand >= nMaxRandForEqualDistribution );

    // Now we know that the random number we have will not favor any result over the
    // others, so just divide it by the upper bound and return the remainder.
    // This will give you a random number within the range of 0 to less than
    // nUpperBound, with each possible result having an equal chance of hitting.
    return ( nRand % nUpperBound );
}

BOOL __stdcall ctrlHandler(DWORD event)
{
	static BOOL shuttingDown = FALSE;

	if (!shuttingDown)
	{
		shuttingDown = TRUE;

		if (serv)
			serv->stop();
	}
	return TRUE;
}
